package com.jzo2o.interceptor;

import com.jzo2o.common.constants.HeaderConstants;
import com.jzo2o.common.handler.RequestIdHandler;
import com.jzo2o.common.handler.UserInfoHandler;
import com.jzo2o.common.model.CurrentUserInfo;
import com.jzo2o.common.utils.Base64Utils;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.common.utils.JsonUtils;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;

/**
 * 向下一个服务传递参数，用户信息、访问来源、访问id
 */import static com.jzo2o.common.constants.HeaderConstants.*;

/**
 * Feign请求拦截器，用于微服务间调用时传递上下文信息
 * 核心作用：向下游服务传递用户信息、访问来源标识和请求ID，确保分布式调用链路中的上下文一致性
 */
@Slf4j
@ConditionalOnBean(value = {UserInfoHandler.class, RequestIdHandler.class})
public class FeignInterceptor implements RequestInterceptor {
    // 用户信息处理器，用于获取当前登录用户信息
    private final UserInfoHandler userInfoHandler;
    // 请求ID处理器，用于获取分布式调用中的唯一请求标识
    private final RequestIdHandler requestIdHandler;

    /**
     * 构造方法注入依赖
     * @param userInfoHandler 用户信息处理器
     * @param requestIdHandler 请求ID处理器
     */
    public FeignInterceptor(UserInfoHandler userInfoHandler, RequestIdHandler requestIdHandler) {
        this.userInfoHandler = userInfoHandler;
        this.requestIdHandler = requestIdHandler;
    }

    /**
     * 拦截Feign请求，添加上下文信息到请求头
     * 具体操作：
     * 1. 将当前用户信息序列化为JSON后进行Base64编码，放入用户信息请求头
     * 2. 添加访问来源标识，标记为内部服务调用
     * 3. 添加请求ID，用于分布式链路追踪
     *
     * @param requestTemplate Feign请求模板，用于设置请求头信息
     */
    @Override
    public void apply(RequestTemplate requestTemplate) {
//         1.用户信息
        CurrentUserInfo userInfo = userInfoHandler.currentUserInfo();
        String userInfoStr = Base64Utils.encodeStr(JsonUtils.toJsonStr(userInfo));
        requestTemplate.header(USER_INFO, userInfoStr);
        // 2.访问来源信息
        requestTemplate.header(HeaderConstants.REQUEST_ORIGIN_FLAG, REQUEST_ORIGIN_FLAG_INNER);
        // 3.访问id
        requestTemplate.header(REQUEST_ID, requestIdHandler.getRequestId());

    }
}
